home *** CD-ROM | disk | FTP | other *** search
- Frequently Asked Questions (FAQS);faqs.432
-
-
-
-
- 1.17) Is there a Perl profiler?
-
- While there isn't one included with the perl source distribution,
- various folks have written packages that allow you to do at least some
- sort of profiling. The strategy usually includes modifying the perl
- debugger to handle profiling. Authors of these packages include
-
- Wayne Thompson <me@anywhere.EBay.Sun.COM>
- Ray Lischner <lisch@sysserver1.mentor.com>
- Kresten Krab Thorup <krab@iesd.auc.dk>
-
- The original articles by these folks containing their
- profilers are available on convex.com in
- /pub/perl/information/profiling.shar via anon ftp.
-
-
- 1.18) Is there a yacc for Perl?
-
- Yes!! It's a version of Berkeley yacc that outputs Perl code instead
- of C code! You can get this from ftp.sterling.com [192.124.9.1] in
- /local/perl-byacc1.8.1.tar.Z, or send the author mail for details.
-
-
- 1.19) How can I use curses with perl?
-
- One way is to build a curseperl binary by linking in your C curses
- library as described in the usub subdirectory of the perl sources.
- This requires a modicum of work, but it will be reasonably fast
- since it's all in C (assuming you consider curses reasonably fast. :-)
- Programs written using this method require the modified curseperl,
- not vanilla perl, to run. While this is something of a disadvantage,
- experience indicates that it's better to use curseperl than to
- try to roll your own using termcap directly.
-
- Another possibility is to use Henk Penning's cterm package, a curses
- emulation library written in perl. cterm is actually a separate
- program with which you communicate via a pipe. It is available from
- ftp.cs.ruu.nl [131.211.80.17] via anonymous ftp. in the directory
- pub/PERL. You may also acquire the package via email in compressed,
- uuencoded form by sending a message to mail-server@cs.ruu.nl
- containing these lines:
-
- begin
- send PERL/cterm.shar.Z
- end
-
- See the question on retrieving perl via mail for more information on
- how to get retrieve other items of interest from the mail server
- there.
-
-
- 1.20) How can I use X with Perl?
-
- Right now, you have several choices. You can wait for perl5, use
- the WAFE or STDWIN packages, or try to make your own usub bindings.
-
- Perl5 is anticipated to be released with bindings for X, called
- guiperl. An exciting prototype for this, written by Jon Biggar
- <jon@netlabs.com>, Larry's *other* brother-in-law and officemate,
- is already up and running inside of Netlabs. This program addresses
- the same dynamic gui-building problem space as does tcl/tk.
-
- If you can't wait or don't think that guiperl will do what you want,
- a stab at Motif bindings was begun by Theodore C. Law
- <TEDLAW@TOROLAB6.VNET.IBM.COM> area. His article about this is
- on convex.com in /pub/perl/info/motif for anon ftp.
-
- STDWIN is a library written by Guido van Rossum <guido@cwi.nl>
- (author of the Python programming language) that is portable
- between Mac, Dos and X11. One could write a Perl agent to
- speak to this STDWIN server.
-
- WAFE is a package that implements a symbolic interface to the Athena
- widgets (X11R5). A typical Wafe application consists in our framework
- of two parts: the front-end (we call it Wafe for Widget[Athena]front
- end) and an application program running typically as separate process.
- The application program can be implemented in an arbitrary programming
- language and talks to the front-end via stdio. Since Wafe (the
- front-end) was developed using the extensible TCL shell (cite John
- Ousterhout), an application program can dynamically submit requests to
- the front-end to build up the graphical user interface; the
- application can even down-load application specific procedures into
- the front-end. The distribution contains sample application programs
- in Perl, GAWK, Prolog, TCL, and C talking to the same Wafe binary.
- Many of the demo applications are implemented in Perl. Wafe 0.9 can
- be obtained via anonymous ftp from
- ftp.wu-wien.ac.at:pub/src/X11/wafe-0.9.tar.Z
- (for people without name server: the ip address is 137.208.3.5)
-
-
- 1.21) What is perl4? What is perl5?
-
- The answer to what is perl4 is nearly anything you might otherwise
- program in shell or C. The answer to what is perl5 is basically
- Perl: the Next Generation. In fact, it's essentially a complete
- rewrite of perl from the bottom up, and back again.
-
- Larry gave a talk on perl5 at a Bay LISA meeting as well as at the
- most recent USENIX LISA conference in Long Beach in which he timorously
- admitted that perl5 might possibly be beta released in early 1993.
- He enumerated some of the following features. Note that not only have
- not all these been implemented yet, the ones further down the list
- might well not get done at all.
-
- a faster, tighter, more flexible interpreter
- very easy GUI Perl applications using X bindings ("guiperl")
- embeddable Perl code in C code: cc prog.c -lperl
- multiple coresident perl interpreters:
- perhaps threading and/or coroutines
- named argument passing:
- some_func( OC => $red, TOF => "\f");
- recursive lists:
- [a, b, [c, d], e] has 4 elts, the 3rd being itself a list
- typed pointers and generalized indirection:
- like @{$aptr} or &{$fptr} or &{ $table[$index] . "func" }().
- merging of list operator and function calling syntax:
- split /pat/, $string;
- subroutines without &'s: myfunc($arg);
- generalization of dbm binding for assoc arrays to handle
- any generic fetch/store/open/close/flush package.
- (thus allowing both dbm and gdbm at once)
- object oriented programming:
- STDOUT->flush(1);
- give dog $bone;
- lexical scoping
- dynamic loading of C libraries for systems that can
- byte-compiled code for speed and maybe security
-
- It's tempting to want this stuff soon, since the sooner it comes
- out the sooner we can all build really cool applications. But the
- longer Larry works on it, the more items from this list will actually
- get done, and the more robust the release will be. So let's not
- ask him about it too often.
-
-
- 1.22) How does Perl compare with languages like REXX or TCL?
-
- REXX is an interpreted programming language first seen on IBM systems,
- and TCL is John Ousterhout's embeddable command language. TCL's most
- intriguing feature for many people is the tcl/tk toolset that allows
- for interpreted X-based tools.
-
- To avoid any flamage, if you really want to know the answer to this
- question, probably the best thing to do is try to write equivalent
- code to do a set of tasks. All three have their own newsgroups in
- which you can learn about (but hopefully not argue about) these
- languages.
-
- To find out more about these or other languages, you might also check
- out David Muir Sharnoff <muir@tfs.com>'s posting on "Catalog of
- compilers, interpreters, and other language tools" which he posts to
- comp.lang.misc, comp.sources.d, comp.archives.admin, and the
- news.answers newsgroups. It's a comprehensive treatment of many
- different languages. (Caveat lector: he considers Perl's syntax
- "unappealing".) This list is archived on convex.com in
- /pub/perl/info/lang-survey.shar .
-
-
- 1.23) Is it a Perl program or a Perl script?
-
- Certainly. :-)
-
- Current UNIX parlance holds that anything interpreted
- is a script, and anything compiled into native machine
- code is a program. However, others hold that a program
- is a program is a program: after all, one seldom discusses
- scripts written in BASIC or LISP. Larry considers it
- a program if it's set in stone and you can't change it,
- whereas if you go in and hack on it, then it's a script.
-
- But doesn't really matter. The terms are generally
- interchangeable today.
-
-
- 1.24) What's the difference between "Perl" and "perl"?
-
- 32 :-) [ ord('p') - ord('P') ]
-
- Larry now uses "Perl" to signify the language proper and "perl" the
- implementation of it, i.e. the current interpreter. Hence my quip
- that "Nothing but perl can parse Perl."
-
- On the other hand, the aesthetic value of casewise parallelism
- in "awk", "sed", and "perl" as much require the lower-case
- version as "C", "Pascal", and "Perl" require the
- upper-case version. It's also easier to type "Perl" in
- typeset print than to be constantly switching in Courier. :-)
-
- In other words, it doesn't matter much, especially if all
- you're doing is hearing someone talk about the language;
- case is hard to distingish aurally.
-
-
- 1.25) What companies use or ship Perl?
-
- At this time, the known list of companies that ship Perl includes at
- least the following:
-
- BSDI
- Comdisco Systems
- CONVEX Computer Corporation
- Dell
- Integraph
- Kubota Pacific (/usr/contrib)
- Netlabs
-
- Many other companies use Perl internally for purposes of tools
- development, systems administration, installation scripts, and test
- suites. Rumor has it that the large workstation vendors (the TLA set)
- are seriously looking into shipping Perl with their standard systems
- "soon".
-
- People with support contracts with their vendors are actively
- encouraged to submit enhancement requests that Perl be shipped
- as part of their standard system. It would, at the very least,
- reduce the FTP load on the Internet. :-)
-
-
- 1.26) Is there commercial, 3rd-party support for Perl?
-
- No. Although perl is included in the GNU distribution, at last check,
- Cygnus does not offer support for it. However, it's unclear whether
- they've ever been offered sufficient financial incentive to do so.
-
- On the other hand, you do have comp.lang.perl as a totally gratis
- support mechanism. As long as you ask "interesting" questions,
- you'll probably get plenty of help. :-)
-
- 1.27) Where can I get a list of the JAPH signature quotes?
-
- These are the "just another perl hacker" signatures that
- some people sign their postings with. About 100 of the
- of the earlier ones are on convex.com in /pub/perl/info/japh.
-
- 1.28) Where can I get a list of Larry Wall witticisms?
-
- Over a hundred quips by Larry, from postings of his or source code,
- can be found on convex.com in /pub/perl/info/lwall-quotes.
-
- 1.29) Is there a pretty-printer for Perl?
-
- That depends on what you mean. If you want something
- that works like vgrind on Perl programs, then the answer
- is "yes, nearly". Here's a vgrind entry for perl:
-
- PERL|perl|Perl:\
- :pb=(^\d?sub\d\p\d?|\{):\
- :bb={:be=}:cb=#:ce=$:sb=":se=\e":lb=':\
- :le=\e':tl:\
- :id=_:\
- :kw=\
- if for foreach unless until while continue else elsif \
- do eval require \
- die exit \
- defined delete reset \
- goto last redo next dump \
- local undef return \
- write format \
- sub package
-
- It doesn't actually do everything right; in particular,
- things like $#, $', s#/foo##, and $foo'bar all confuse it.
-
- If what you mean is whether there is a program that will
- reformat the program much as indent(1) will do for C, then
- the answer is no. The complex feedback between the scanner
- and the parser (as in the things that confuse vgrind) make
- it challenging to write at best to write a stand-alone C parser.
- --
- Tom Christiansen tchrist@convex.com convex!tchrist
-
- California is a fine place to live -- if you happen to be an orange.
- -- Fred Allen
- --
- Tom Christiansen tchrist@convex.com convex!tchrist
-
- As far as we know, our computer has never had an undetected error.
- -- Weisert
- Xref: bloom-picayune.mit.edu comp.lang.perl:14079 news.answers:4268
- Path: bloom-picayune.mit.edu!enterpoop.mit.edu!usc!cs.utexas.edu!uunet!olivea!pagesat!spssig.spss.com!news.oc.com!convex!tchrist
- From: tchrist@convex.COM (Tom Christiansen)
- Newsgroups: comp.lang.perl,news.answers
- Subject: comp.lang.perl FAQ (part 2 of 2)
- Message-ID: <1992Nov30.130440.11167@news.eng.convex.com>
- Date: 30 Nov 92 13:04:40 GMT
- Expires: Mon, 4 Jan 1993 12:00:00 GMT
- References: <1992Nov30.124619.8579@news.eng.convex.com>
- Sender: usenet@news.eng.convex.com (news access account)
- Reply-To: tchrist@convex.COM (Tom Christiansen)
- Followup-To: comp.lang.perl
- Organization: Convex Computer Corporation, Colorado Springs, CO
- Lines: 1348
- Approved: news-answers-request@MIT.Edu
- Originator: tchrist@pixel.convex.com
- Nntp-Posting-Host: pixel.convex.com
- X-Disclaimer: This message was written by a user at CONVEX Computer
- Corp. The opinions expressed are those of the user and
- not necessarily those of CONVEX.
-
- Archive-name: perl-faq/part2
- Version: $Id: perl-tech,v 1.2 92/11/30 05:22:44 tchrist Exp Locker: tchrist $
-
- This posting contains answers to the following techical questions
- regarding Perl:
-
- 2.1) What are all these $@*%<> signs and how do I know when to use them?
- 2.2) Why don't backticks work as they do in shells?
- 2.3) How come Perl operators have different precedence than C operators?
- 2.4) How come my converted awk/sed/sh script runs more slowly in Perl?
- 2.5) How can I call my system's unique C functions from Perl?
- 2.6) Where do I get the include files to do ioctl() or syscall()?
- 2.7) Why doesn't "local($foo) = <FILE>;" work right?
- 2.8) How can I detect keyboard input without reading it?
- 2.9) How can I make an array of arrays or other recursive data types?
- 2.10) How can I quote a variable to use in a regexp?
- 2.11) Why do setuid Perl scripts complain about kernel problems?
- 2.12) How do I open a pipe both to and from a command?
- 2.13) How can I change the first N letters of a string?
- 2.14) How can I manipulate fixed-record-length files?
- 2.15) How can I make a file handle local to a subroutine?
- 2.16) How can I extract just the unique elements of an array?
- 2.17) How can I call alarm() or usleep() from Perl?
- 2.18) How can I test whether an array contains a certain element?
- 2.19) How can I do an atexit() or setjmp()/longjmp() in Perl?
- 2.20) Why doesn't Perl interpret my octal data octally?
- 2.21) How do I sort an associative array by value instead of by key?
- 2.22) How can I capture STDERR from an external command?
- 2.23) Why doesn't open return an error when a pipe open fails?
- 2.24) How can I compare two date strings?
- 2.25) What's the fastest way to code up a given task in perl?
- 2.26) How can I know how many entries are in an associative array?
- 2.27) Why can't my perl program read from STDIN after I gave it ^D (EOF) ?
- 2.28) Do I always/never have to quote my strings or use semicolons?
- 2.29) How can I translate tildes in a filename?
- 2.30) How can I convert my shell script to Perl?
- 2.31) What is variable suicide and how can I prevent it?
- 2.32) Can I use Perl regular expressions to match balanced text?
- 2.33) Can I use Perl to run a telnet or ftp session?
- 2.34) What does "Malformed command links" mean?
- 2.35) How can I set up a footer format to be used with write()?
- 2.36) Why does my Perl program keep growing in size?
-
-
- 2.1) What are all these $@*%<> signs and how do I know when to use them?
-
- Those are type specifiers: $ for scalar values, @ for indexed arrays,
- and % for hashed arrays. The * means all types of that symbol name
- and are sometimes used like pointers; the <> are used for inputting
- a record from a filehandle. See the question on arrays of arrays
- for more about Perl pointers.
-
- Always make sure to use a $ for single values and @ for multiple ones.
- Thus element 2 of the @foo array is accessed as $foo[2], not @foo[2],
- which is a list of length one (not a scalar), and is a fairly common
- novice mistake. Sometimes you can get by with @foo[2], but it's
- not really doing what you think it's doing for the reason you think
- it's doing it, which means one of these days, you'll shoot yourself
- in the foot; ponder for a moment what these will really do:
- @foo[0] = `cmd args`;
- @foo[2] = <FILE>;
- Just always say $foo[2] and you'll be happier.
-
- This may seem confusing, but try to think of it this way: you use the
- character of the type which you *want back*. You could use @foo[1..3] for
- a slice of three elements of @foo, or even @foo{A,B,C} for a slice of
- of %foo. This is the same as using ($foo[1], $foo[2], $foo[3]) and
- ($foo{A}, $foo{B}, $foo{C}) respectively. In fact, you can even use
- lists to subscript arrays and pull out more lists, like @foo[@bar] or
- @foo{@bar}, where @bar is in both cases presumably a list of subscripts.
-
- While there are a few places where you don't actually need these type
- specifiers, except for files, you should always use them. Note that
- <FILE> is NOT the type specifier for files; it's the equivalent of awk's
- getline function, that is, it reads a line from the handle FILE. When
- doing open, close, and other operations besides the getline function on
- files, do NOT use the brackets.
-
- Beware of saying:
- $foo = BAR;
- Which wil be interpreted as
- $foo = 'BAR';
- and not as
- $foo = <BAR>;
- If you always quote your strings, you'll avoid this trap.
-
- Normally, files are manipulated something like this (with appropriate
- error checking added if it were production code):
-
- open (FILE, ">/tmp/foo.$$");
- print FILE "string\n";
- close FILE;
-
- If instead of a filehandle, you use a normal scalar variable with file
- manipulation functions, this is considered an indirect reference to a
- filehandle. For example,
-
- $foo = "TEST01";
- open($foo, "file");
-
- After the open, these two while loops are equivalent:
-
- while (<$foo>) {}
- while (<TEST01>) {}
-
- as are these two statements:
-
- close $foo;
- close TEST01;
-
- but NOT to this:
-
- while (<$TEST01>) {} # error
- ^
- ^ note spurious dollar sign
-
- This is another common novice mistake; often it's assumed that
-
- open($foo, "output.$$");
-
- will fill in the value of $foo, which was previously undefined.
- This just isn't so -- you must set $foo to be the name of a valid
- filehandle before you attempt to open it.
-
-
- 2.2) Why don't backticks work as they do in shells?
-
- Several reason. One is because backticks do not interpolate within
- double quotes in Perl as they do in shells.
-
- Let's look at two common mistakes:
-
- $foo = "$bar is `wc $file`"; # WRONG
-
- This should have been:
-
- $foo = "$bar is " . `wc $file`;
-
- But you'll have an extra newline you might not expect. This
- does not work as expected:
-
- $back = `pwd`; chdir($somewhere); chdir($back); # WRONG
-
- Because backticks do not automatically eat trailing or embedded
- newlines. The chop() function will remove the last character from
- a string. This should have been:
-
- chop($back = `pwd`); chdir($somewhere); chdir($back);
-
- You should also be aware that while in the shells, embedding
- single quotes will protect variables, in Perl, you'll need
- to escape the dollar signs.
-
- Shell: foo=`cmd 'safe $dollar'`
- Perl: $foo=`cmd 'safe \$dollar'`;
-
-
- 2.3) How come Perl operators have different precedence than C operators?
-
- Actually, they don't; all C operators have the same precedence in Perl as
- they do in C. The problem is with a class of functions called list
- operators, e.g. print, chdir, exec, system, and so on. These are somewhat
- bizarre in that they have different precedence depending on whether you
- look on the left or right of them. Basically, they gobble up all things
- on their right. For example,
-
- unlink $foo, "bar", @names, "others";
-
- will unlink all those file names. A common mistake is to write:
-
- unlink "a_file" || die "snafu";
-
- The problem is that this gets interpreted as
-
- unlink("a_file" || die "snafu");
-
- To avoid this problem, you can always make them look like function calls
- or use an extra level of parentheses:
-
- (unlink "a_file") || die "snafu";
- unlink("a_file") || die "snafu";
-
- Sometimes you actually do care about the return value:
-
- unless ($io_ok = print("some", "list")) { }
-
- Yes, print() return I/O success. That means
-
- $io_ok = print(2+4) * 5;
-
- returns 5 times whether printing (2+4) succeeded, and
- print(2+4) * 5;
- returns the same 5*io_success value and tosses it.
-
- See the Perl man page's section on Precedence for more gory details,
- and be sure to use the -w flag to catch things like this.
-
-
- 2.4) How come my converted awk/sed/sh script runs more slowly in Perl?
-
- The natural way to program in those languages may not make for the fastest
- Perl code. Notably, the awk-to-perl translator produces sub-optimal code;
- see the a2p man page for tweaks you can make.
-
- Two of Perl's strongest points are its associative arrays and its regular
- expressions. They can dramatically speed up your code when applied
- properly. Recasting your code to use them can help a lot.
-
- How complex are your regexps? Deeply nested sub-expressions with {n,m} or
- * operators can take a very long time to compute. Don't use ()'s unless
- you really need them. Anchor your string to the front if you can.
-
- Something like this:
- next unless /^.*%.*$/;
- runs more slowly than the equivalent:
- next unless /%/;
-
- Note that this:
- next if /Mon/;
- next if /Tue/;
- next if /Wed/;
- next if /Thu/;
- next if /Fri/;
- runs faster than this:
- next if /Mon/ || /Tue/ || /Wed/ || /Thu/ || /Fri/;
- which in turn runs faster than this:
- next if /Mon|Tue|Wed|Thu|Fri/;
- which runs *much* faster than:
- next if /(Mon|Tue|Wed|Thu|Fri)/;
-
- There's no need to use /^.*foo.*$/ when /foo/ will do.
-
- Remember that a printf costs more than a simple print.
-
- Don't split() every line if you don't have to.
-
- Another thing to look at is your loops. Are you iterating through
- indexed arrays rather than just putting everything into a hashed
- array? For example,
-
- @list = ('abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stv');
-
- for $i ($[ .. $#list) {
- if ($pattern eq $list[$i]) { $found++; }
- }
-
- First of all, it would be faster to use Perl's foreach mechanism
- instead of using subscripts:
-
- foreach $elt (@list) {
- if ($pattern eq $elt) { $found++; }
- }
-
- Better yet, this could be sped up dramatically by placing the whole
- thing in an associative array like this:
-
- %list = ('abc', 1, 'def', 1, 'ghi', 1, 'jkl', 1,
- 'mno', 1, 'pqr', 1, 'stv', 1 );
- $found += $list{$pattern};
-
- (but put the %list assignment outside of your input loop.)
-
- You should also look at variables in regular expressions, which is
- expensive. If the variable to be interpolated doesn't change over the
- life of the process, use the /o modifier to tell Perl to compile the
- regexp only once, like this:
-
- for $i (1..100) {
- if (/$foo/o) {
- &some_func($i);
- }
- }
-
- Finally, if you have a bunch of patterns in a list that you'd like to
- compare against, instead of doing this:
-
- @pats = ('_get.*', 'bogus', '_read', '.*exit', '_write');
- foreach $pat (@pats) {
- if ( $name =~ /^$pat$/ ) {
- &some_func();
- last;
- }
- }
-
- If you build your code and then eval it, it will be much faster.
- For example:
-
- @pats = ('_get.*', 'bogus', '_read', '.*exit', '_write');
- $code = <<EOS
- while (<>) {
- study;
- EOS
- foreach $pat (@pats) {
- $code .= <<EOS
- if ( /^$pat\$/ ) {
- &some_func();
- next;
- }
- EOS
- }
- $code .= "}\n";
- print $code if $debugging;
- eval $code;
-
-
-
- 2.5) How can I call my system's unique C functions from Perl?
-
- If these are system calls and you have the syscall() function, then
- you're probably in luck -- see the next question. For arbitrary
- library functions, it's not quite so straight-forward. While you
- can't have a C main and link in Perl routines, if you're
- determined, you can extend Perl by linking in your own C routines.
- See the usub/ subdirectory in the Perl distribution kit for an example
- of doing this to build a Perl that understands curses functions. It's
- neither particularly easy nor overly-documented, but it is feasible.
-
-
- 2.6) Where do I get the include files to do ioctl() or syscall()?
-
- These are generated from your system's C include files using the h2ph
- script (once called makelib) from the Perl source directory. This will
- make files containing subroutine definitions, like &SYS_getitimer, which
- you can use as arguments to your function.
-
- You might also look at the h2pl subdirectory in the Perl source for how to
- convert these to forms like $SYS_getitimer; there are both advantages and
- disadvantages to this. Read the notes in that directory for details.
-
- In both cases, you may well have to fiddle with it to make these work; it
- depends how funny-looking your system's C include files happen to be.
-
- If you're trying to get at C structures, then you should take a look
- at using c2ph, which uses debugger "stab" entries generated by your
- BSD or GNU C compiler to produce machine-independent perl definitions
- for the data structures. This allows to you avoid hardcoding
- structure layouts, types, padding, or sizes, greatly enhancing
- portability. c2ph comes with the perl distribution. On an SCO
- system, GCC only has COFF debugging support by default, so you'll have
- to build GCC 2.1 with DBX_DEBUGGING_INFO defined, and use -gstabs to
- get c2ph to work there.
-
- See the file /pub/perl/info/ch2ph on convex.com via anon ftp
- for more traps and tips on this process.
-
-
- 2.7) Why doesn't "local($foo) = <FILE>;" work right?
-
- Well, it does. The thing to remember is that local() provides an array
- context, and that the <FILE> syntax in an array context will read all the
- lines in a file. To work around this, use:
-
- local($foo);
- $foo = <FILE>;
-
- You can use the scalar() operator to cast the expression into a scalar
- context:
-
- local($foo) = scalar(<FILE>);
-
-
- 2.8) How can I detect keyboard input without reading it?
-
- You should check out the Frequently Asked Questions list in
- comp.unix.* for things like this: the answer is essentially the same.
- It's very system dependent. Here's one solution that works on BSD
- systems:
-
- sub key_ready {
- local($rin, $nfd);
- vec($rin, fileno(STDIN), 1) = 1;
- return $nfd = select($rin,undef,undef,0);
- }
-
- A closely related question is how to input a single character from the
- keyboard. Again, this is a system dependent operation. The following
- code that may or may not help you:
-
- $BSD = -f '/vmunix';
- if ($BSD) {
- system "stty cbreak </dev/tty >/dev/tty 2>&1";
- }
- else {
- system "stty", '-icanon',
- system "stty", 'eol', "\001";
- }
-
- $key = getc(STDIN);
-
- if ($BSD) {
- system "stty -cbreak </dev/tty >/dev/tty 2>&1";
- }
- else {
- system "stty", 'icanon';
- system "stty", 'eol', '^@'; # ascii null
- }
- print "\n";
-
- You could also handle the stty operations yourself for speed if you're
- going to be doing a lot of them. This code works to toggle cbreak
- and echo modes on a BSD system:
-
- sub set_cbreak { # &set_cbreak(1) or &set_cbreak(0)
- local($on) = $_[0];
- local($sgttyb,@ary);
- require 'sys/ioctl.ph';
- $sgttyb_t = 'C4 S' unless $sgttyb_t; # c2ph: &sgttyb'typedef()
-
- ioctl(STDIN,&TIOCGETP,$sgttyb) || die "Can't ioctl TIOCGETP: $!";
-
- @ary = unpack($sgttyb_t,$sgttyb);
- if ($on) {
- $ary[4] |= &CBREAK;
- $ary[4] &= ~&ECHO;
- } else {
- $ary[4] &= ~&CBREAK;
- $ary[4] |= &ECHO;
- }
- $sgttyb = pack($sgttyb_t,@ary);
-
- ioctl(STDIN,&TIOCSETP,$sgttyb) || die "Can't ioctl TIOCSETP: $!";
- }
-
- Note that this is one of the few times you actually want to use the
- getc() function; it's in general way too expensive to call for normal
- I/O. Normally, you just use the <FILE> syntax, or perhaps the read()
- or sysread() functions.
-
- For perspectives on more portable solutions, use anon ftp to retrieve
- the file /pub/perl/info/keypress from convex.com.
-
-
- 2.9) How can I make an array of arrays or other recursive data types?
-
- Remember that Perl isn't about nested data structures (actually,
- perl0 .. perl4 weren't, but maybe perl5 will be, at least
- somewhat). It's about flat ones, so if you're trying to do this, you
- may be going about it the wrong way or using the wrong tools. You
- might try parallel arrays with common subscripts.
-